home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / suckmods.zip / SUCK05 / SRC / RUNES.QC < prev    next >
Text File  |  1997-05-12  |  29KB  |  1,030 lines

  1. void (vector org) spawn_tfog;
  2. void(vector org, entity death_owner) spawn_tdeath;
  3. void() bound_other_ammo;
  4. void() W_SetCurrentAmmo;
  5.  
  6.  
  7. float (entity targ, entity attacker) CalculateDamageModifier =
  8. {
  9. };
  10.  
  11. entity() SelectRuneSpawnPoint =
  12. {
  13.     runespawn = find(runespawn, classname, "info_player_deathmatch");
  14.     if (runespawn == world)
  15.         runespawn = find (runespawn, classname, "info_player_deathmatch");
  16.     if (runespawn == world)
  17.         error("no info_player_deathmatch to spawn rune");
  18.     return runespawn;
  19. };
  20.  
  21.  
  22.  
  23. void() RuneTouch =
  24. {
  25.     local string    s;
  26.     local    float    best;
  27.     local        entity    stemp;
  28.     
  29.     if ((other.classname != "player") || (other.health <= 0)) 
  30.         return;
  31.  
  32.     if (teamplay&TEAM_RUNES_YGGDRASIL)
  33.     {
  34.         if (((self.rune_num <= rune_set_1) && (self.rune_num >
  35.         (rune_set_1 - RUNE_SET_SIZE))) && (other.team != (TEAM_COLOR1 + 1)))
  36.             return;
  37.         if (((self.rune_num <= rune_set_2) && (self.rune_num >
  38.         (rune_set_2 - RUNE_SET_SIZE))) && (other.team != (TEAM_COLOR2 + 1)))
  39.             return;
  40.     }
  41.  
  42.     if (other.rune_num != 0) {
  43.         if (other.rune_notice_time < time) {
  44. //            sprint(other, "You already have a rune.\n");
  45.             other.rune_notice_time = time + 5;
  46.         }
  47.         return; // one per customer
  48.     }
  49.         
  50.     other.rune_num = self.rune_num;
  51.     
  52.     // backpack touch sound
  53.     playsound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  54.     stuffcmd (other, "bf\n");
  55.  
  56.     RuneGrab();
  57.  
  58.     remove(self);
  59.  
  60.  
  61.     self=other;
  62.     self.rune_pickup_time=time;
  63. };
  64.  
  65. void (float flag) Do_DropRune;
  66.  
  67. void() RuneRespawn =
  68. {
  69.     local entity oself;
  70.  
  71.     oself = self;
  72.  
  73.     // choose random starting points
  74.     self = SelectRuneSpawnPoint();
  75.     Do_DropRune(oself.rune_num);
  76.  
  77.     remove(oself);
  78. };
  79.  
  80.  
  81. void (float runenum) Do_DropRune = 
  82. {
  83.     local entity    item, oself;
  84.  
  85.  
  86.  
  87.     item = spawn();
  88.     item.origin = self.origin - '0 0 24';
  89.     item.rune_num = runenum;
  90.     oself=self;
  91.     self=item;
  92.  
  93.     // SUCK: Set the model, movetype, size, etc.
  94.     InitRune();
  95.  
  96.     self=oself;
  97. };
  98.  
  99. /*
  100. ===============
  101. Droprune
  102. self is player
  103. ===============
  104. */
  105. void() DropRune =
  106. {
  107.     if (self.rune_num == 0)
  108.         return;
  109.  
  110.     if (self.rune_num == ITEM_RUNE_THOR)
  111.     {
  112.         self.effects=self.effects-(self.effects&EF_BRIGHTFIELD);
  113.         self.items=self.items-(self.items&IT_LIGHTNING);
  114.         self.ammo_cells=0;
  115.     }
  116.     if (self.rune_num == ITEM_RUNE_ALIBABA)
  117.         remove(self.bulb);    
  118.  
  119.     Do_DropRune(self.rune_num);
  120.     self.rune_num = 0;
  121. };
  122.  
  123.  
  124. /*
  125. ================
  126. SpawnRunes
  127. self is the entity that was created for us, we remove it
  128. ================
  129. */
  130. void() SpawnRunes =
  131. {
  132.     local entity oself, some_rune;
  133.     local float curr_rune, i, bitfield, nshift, nocollide, bitor;
  134.     local string s;
  135.     dprint("spawning runes..\n");
  136.  
  137.     if (runespawned) {
  138.         remove(self);
  139.         return;
  140.     }
  141.  
  142.     oself = self;
  143.  
  144.     // choose random starting points
  145.     curr_rune = random() * 10;
  146.     while (curr_rune > 0) 
  147.     {
  148.         self = SelectRuneSpawnPoint();
  149.         curr_rune = curr_rune - 1;
  150.     }
  151.  
  152.     // This is the most simple rune spawn mode.
  153.     // Just spawn the first rune_group_size runes.
  154.     if (teamplay&TEAM_RUNES_GROUP)
  155.     {
  156.         dprint("MODE>>>>>.RUNES_GROUP\n");
  157.         curr_rune = rune_group_size;
  158.         while (curr_rune > 0) 
  159.         {
  160.             self=SelectRuneSpawnPoint();
  161.             Do_DropRune(curr_rune);
  162.             curr_rune = curr_rune - 1;
  163.         }
  164.     }
  165.     // TEAM_RUNES_RANDOM means spawn rune_group_size
  166.     // runes, chosen at random (they may not be unique).
  167.     else if (teamplay&TEAM_RUNES_RANDOM)
  168.     {
  169.         dprint("MODE>>>>>.RUNES_RAND\n");
  170.         curr_rune=rune_group_size;
  171.         while (curr_rune > 0)
  172.         {
  173.             i = random();
  174.             i = i * RUNE_NUM_RUNES;
  175.             i = ceil(i);
  176.             self=SelectRuneSpawnPoint();
  177.             Do_DropRune(i);
  178.             curr_rune = curr_rune - 1;
  179.         }
  180.     }
  181.     else if (teamplay&TEAM_RUNES_SETS)
  182.     {
  183.         if (teamplay&TEAM_RUNES_YGGDRASIL)
  184.         {
  185.             dprint("MODE>>>>>.RUNES_SETS+YGGDRASIL\n");
  186.             // Select two rune sets at random.
  187.             rune_set_1 = random() * (RUNE_NUM_RUNES / RUNE_SET_SIZE);
  188.             rune_set_1 = ceil(rune_set_1);
  189.             if (rune_set_1 == 0) rune_set_1 = 1;
  190.             rune_set_2 = rune_set_1;
  191.             while (rune_set_2 == rune_set_1)
  192.             {
  193.                 rune_set_2 = random() * (RUNE_NUM_RUNES / RUNE_SET_SIZE);
  194.                 rune_set_2 = ceil(rune_set_2);
  195.                 if (rune_set_2 == 0) rune_set_2 = 1;
  196.             }
  197.             rune_set_1 = rune_set_1 * RUNE_SET_SIZE;
  198.             rune_set_2 = rune_set_2 * RUNE_SET_SIZE;
  199.     
  200.             // Spawn rune set 1.
  201.             curr_rune = rune_set_1;
  202.             while (curr_rune > (rune_set_1 - RUNE_SET_SIZE))
  203.             {
  204.                 self=SelectRuneSpawnPoint();
  205.                 Do_DropRune(curr_rune);
  206.                 curr_rune = curr_rune - 1;
  207.             }
  208.             // Spawn rune set 2.
  209.             curr_rune = rune_set_2;
  210.             while (curr_rune > (rune_set_2 - RUNE_SET_SIZE))
  211.             {
  212.                 self=SelectRuneSpawnPoint();
  213.                 Do_DropRune(curr_rune);
  214.                 curr_rune = curr_rune - 1;
  215.             }
  216.             
  217.         }
  218.         // The below code is very hard to read and is
  219.         // optimized so that we don't have to traverse
  220.         // a linked list to avoid collisions in O(n^2) time.
  221.         // Only mess with it if you really know what you're doing.
  222.         else
  223.         {
  224.             bitfield = 0;
  225.             i = num_rune_sets;
  226.  
  227.             // trying to spawn more rune sets than we have
  228.             // will result in an infinite loop, so:
  229.             if (i > (RUNE_NUM_RUNES / RUNE_SET_SIZE))
  230.                 i = (RUNE_NUM_RUNES / RUNE_SET_SIZE);
  231.             dprint("** TOTAL RUNE SETS TO SPAWN: ");
  232.             s=ftos(i); dprint(s); dprint("\n");
  233.             while (i > 0)
  234.             {
  235.                 s=ftos(i);
  236.                 dprint("Spawning rune set ");
  237.                 dprint(s);
  238.                 dprint("\n");
  239.                 // choose a rune set at random and
  240.                 // make sure it is unique
  241.                 nocollide = 0;
  242.                 while (nocollide == 0)
  243.                 {
  244.                     rune_set_1 = random() * (RUNE_NUM_RUNES    / RUNE_SET_SIZE);
  245.                     nshift = rune_set_1 = ceil(rune_set_1);
  246.                     s=ftos(rune_set_1);
  247.                     dprint("Chose rune set ");
  248.                     dprint(s);
  249.                     dprint("\n");
  250.                     // Shift left by nshift bits
  251.                     bitor=1;
  252.                     while (nshift > 0)
  253.                     {
  254.                         bitor = bitor * 2;
  255.                         nshift = nshift - 1;
  256.                     }
  257.                     if ((bitfield&bitor) == 0)
  258.                     {
  259.                         bitfield = bitfield|bitor;
  260.                         nocollide = 1;
  261.                     }
  262.                     if (nocollide == 1)
  263.                         dprint("Unique.\n");
  264.                     else
  265.                         dprint("It collided\n");
  266.                 }
  267.                 curr_rune = rune_set_1 = rune_set_1 * RUNE_SET_SIZE;
  268.                 while (curr_rune > (rune_set_1 - RUNE_SET_SIZE))
  269.                 {
  270.                     dprint("Spawning rune ");
  271.                     s=ftos(curr_rune);
  272.                     dprint(s);
  273.                     dprint(".\n");
  274.                     self=SelectRuneSpawnPoint();
  275.                     Do_DropRune(curr_rune);
  276.                     curr_rune = curr_rune - 1;
  277.                 }
  278.                 i = i - 1;
  279.             }
  280.         }
  281.  
  282.     }
  283.  
  284.     runespawned = 1;
  285.  
  286.     remove(oself);
  287. };
  288.  
  289. void() TossRune =
  290. {
  291.     local entity item, oself;
  292.     local float runenum;
  293.  
  294.     runenum = self.rune_num;
  295.  
  296.     if (self.rune_num == 0)
  297.         return;
  298.  
  299.     if (!(teamplay&TEAM_DROP_RUNES))
  300.     {
  301.         self.msg_center = 1;
  302.         clientmsg(self, "Rune dropping is disabled.\n");
  303.         return;
  304.     }
  305.  
  306.     if ((self.rune_num == ITEM_RUNE_VAMPIRE) && (self.rune_pickup_time<(time - 5)))
  307.     {
  308.         self.msg_center=1;
  309.         clientmsg(self, "It is too late to escape, vampire.\n");
  310.         return;
  311.     }
  312.     else if (self.rune_num == ITEM_RUNE_VAMPIRE)
  313.     {
  314.         self.max_health = 100;
  315.     }
  316.     if (self.rune_num == ITEM_RUNE_WEREWOLF)
  317.         self.touch = SUB_Null;
  318.     else
  319.     if (self.rune_num == ITEM_RUNE_ALIBABA)
  320.         self.touch = SUB_Null;
  321.     else
  322.     if (self.rune_num == ITEM_RUNE_LOKI)
  323.     {
  324.         setmodel(self, "progs/player.mdl");
  325.         msg_entity=self;
  326.         WriteByte(MSG_ONE, 5);
  327.         WriteEntity(MSG_ONE, self);
  328.     }
  329.     if (self.rune_num == ITEM_RUNE_HERMES)
  330.     {
  331.         self.movetype=MOVETYPE_WALK;
  332.         self.flags=self.flags-FL_INWATER;
  333.         self.waterlevel=0;
  334.         self.air_finished=0;
  335. //        self.armorvalue = self.armorvalue * 2;
  336.     }
  337.     else
  338.     if (self.rune_num == ITEM_RUNE_THOR)
  339.     {
  340.         self.effects=self.effects-(self.effects&EF_BRIGHTFIELD);
  341.         self.items=self.items-(self.items&IT_LIGHTNING);
  342.         self.ammo_cells=0;
  343.     }
  344.     else
  345.     if (self.rune_num == ITEM_RUNE_POSEIDON)
  346.     {
  347.         self.items=self.items-(self.items&IT_LIGHTNING);
  348.         self.ammo_cells=0;
  349.     }
  350.     else if (self.rune_num == ITEM_RUNE_ALIBABA)
  351.         remove(self.bulb);
  352.  
  353.     if (self.had_tbolt > 0)
  354.         self.items = self.items | IT_LIGHTNING;
  355.     self.had_tbolt = 0;
  356.  
  357.     self.rune_num=0;
  358.  
  359.     item = spawn();
  360.  
  361.     makevectors(self.v_angle);
  362.     setorigin(item, self.origin + '0 0 24');
  363.         item.velocity = aim(self, 1000);
  364.         item.velocity = item.velocity * 3000;
  365.     item.rune_num = runenum;
  366.  
  367.     oself=self;
  368.     self=item;
  369.  
  370.     // SUCK: Set the model, movetype, size, etc.
  371.     InitRune();
  372.     item=self;
  373.     self=oself;
  374.  
  375.     // Deal with people dropping the ammo rune.
  376.     bound_other_ammo();
  377.     self.effects=self.effects-(self.effects&EF_BRIGHTFIELD);
  378. };
  379.  
  380. void(entity e, float chan, string samp, float vol, float atten) playsound = 
  381. {
  382.     if (e.rune_num != ITEM_RUNE_NINJA)
  383.         sound(e, chan, samp, vol, atten);
  384. };
  385.  
  386.  
  387. // Touch functions
  388. void() werewolf_touch =
  389. {
  390.     if ((other.classname == "player") && (other.health > 0) &&
  391.         (other.team != self.team) &&
  392.         (self.rune_num == ITEM_RUNE_WEREWOLF))
  393.     {
  394.         other.deathweapon="werewolf";
  395.         T_Damage(other, self, self, 5);
  396.         other.deathweapon="";
  397.     }    
  398. };
  399.  
  400. void() alibaba_touch =
  401. {
  402.     local float take;
  403.     local entity oself;    
  404.     if ((other.classname !="player") || (other.health <= 0) ||
  405.         (other.team == self.team))
  406.         return;
  407.     
  408.     if (self.rune_num == ITEM_RUNE_ALIBABA)
  409.     {
  410.         if (other.ammo_shells > 15)
  411.             other.ammo_shells = 15;
  412.         if (other.ammo_nails > 20)
  413.             other.ammo_nails = 20;
  414.         if (other.ammo_rockets > 5)
  415.             other.ammo_rockets = 5;
  416.         if (other.ammo_cells > 5)
  417.             other.ammo_cells = 5;
  418.  
  419.         oself=self;
  420.         self=other;
  421.         W_SetCurrentAmmo();
  422.         self=oself;
  423.         clientmsg(self, "You have relieved the enemy of\nhis ammo!\n");
  424.  
  425.         self.ammo_shells = self.ammo_shells + 10;
  426.         self.ammo_nails = self.ammo_nails + 20;
  427.         self.ammo_rockets = self.ammo_rockets + 5;
  428.         self.ammo_cells = self.ammo_cells + 5;
  429.         oself=other;
  430.         other=self;
  431.         bound_other_ammo();
  432.         other=oself;
  433.         W_SetCurrentAmmo();
  434.     }
  435. }; 
  436.  
  437.  
  438. void () KiziTeleportToBase =
  439. {
  440.     local entity e, f;
  441.     local float got_spot, occupied;
  442.     local string kizibaseclass;
  443.     local float occupied;
  444.  
  445.     // Can't teleport to base with the flag, silly.
  446.     if (self.player_flag&ITEM_ENEMY_FLAG)
  447.         return;
  448.  
  449.     // Which base should we teleport to.
  450.     if (self.team == (TEAM_COLOR1 + 1))
  451.         kizibaseclass = "info_player_team1";
  452.     else
  453.         kizibaseclass = "info_player_team2";    
  454.  
  455.     // Find a clear spot
  456.     got_spot = 0;
  457.     e=find(world, classname, kizibaseclass);
  458.     while ((got_spot != 1) && (e!=world))
  459.     {
  460.         occupied = 0;
  461.         f=findradius(e.origin, 50);
  462.         if (f)
  463.         {
  464.             while (!occupied && !(!f)) 
  465.             {
  466.                 if (f.classname == "player" && f.health>0)
  467.                     occupied = 1;
  468.                 else
  469.                     f = f.chain;
  470.             }
  471.         }
  472.  
  473.         if (occupied)
  474.             e = find(e, classname, kizibaseclass);
  475.         else
  476.             got_spot = 1;
  477.  
  478.     }
  479.  
  480.     if (e == world) return;
  481.  
  482.     // Teleport him.
  483.     spawn_tfog(self.origin);
  484.     spawn_tfog(e.origin);
  485.     spawn_tdeath(e.origin, self);
  486.     setorigin(self, e.origin);    
  487. };
  488.  
  489. void () ShogunTeleport =
  490. {
  491.     local entity e, f;
  492.     local float got_spot, occupied;
  493.     local string shogunbaseclass;
  494.     local float occupied;
  495.  
  496.     // Can't teleport to base with the flag, silly.
  497.     if (self.player_flag&ITEM_ENEMY_FLAG)
  498.         return;
  499.  
  500.     // Which base should we teleport to.
  501.     if (self.team == (TEAM_COLOR1 + 1))
  502.         shogunbaseclass = "info_player_team2";
  503.     else
  504.         shogunbaseclass = "info_player_team1";    
  505.  
  506.     // Find a clear spot
  507.     got_spot = 0;
  508.     e=find(world, classname, shogunbaseclass);
  509.     while ((got_spot != 1) && (e!=world))
  510.     {
  511.         occupied = 0;
  512.         f=findradius(e.origin, 50);
  513.         if (f)
  514.         {
  515.             while (!occupied && !(!f)) 
  516.             {
  517.                 if (f.classname == "player" && f.health>0)
  518.                     occupied = 1;
  519.                 else
  520.                     f = f.chain;
  521.             }
  522.         }
  523.         if (occupied)
  524.             e = find(e, classname, shogunbaseclass);
  525.         else
  526.             got_spot = 1;
  527.  
  528.         if (!got_spot)
  529.             e = find(e, classname, shogunbaseclass);
  530.     }
  531.  
  532.     if (e == world) return;
  533.  
  534.     // Teleport him.
  535.     spawn_tfog(self.origin);
  536.     spawn_tfog(e.origin);
  537.     spawn_tdeath(e.origin, self);
  538.     setorigin(self, e.origin);    
  539. };
  540.  
  541. // Rune initialization functions.  The player is always 'other' for these.
  542. void() rinit_vampire =
  543. {
  544.     other.max_health = 130;
  545. };
  546.  
  547. void() rinit_werewolf =
  548. {
  549.     other.touch = werewolf_touch;
  550. };
  551. void() rinit_samauri  =
  552. {
  553. };
  554.  
  555. void() rinit_hermes =
  556. {
  557.     other.movetype=MOVETYPE_FLY;
  558. /*
  559.     if ((other.items|IT_ARMOR1) && (other.armorvalue > 50))
  560.         other.armorvalue=50;
  561.     else if ((other.items|IT_ARMOR2) && (other.armorvalue > 75))
  562.         other.armorvalue=75;
  563.     else if ((other.items|IT_ARMOR3) && (other.armorvalue > 100))
  564.         other.armorvalue=100;
  565. */
  566. };
  567.  
  568. void() rinit_thor =
  569. {
  570.     other.had_tbolt = (other.items&IT_LIGHTNING);
  571.     other.effects=other.effects|EF_BRIGHTFIELD;
  572.     other.items=other.items|IT_LIGHTNING;
  573.     other.ammo_cells=1;
  574. };
  575.  
  576. void() rinit_loki =
  577. {
  578.     other.loki_invis=0;
  579.     other.rune_time = time;
  580.     other.loki_ghosted=0;
  581.     other.loki_possessed=0;
  582.     other.loki_forcevis=0;
  583.     other.armorvalue=0;
  584.     other.items=other.items-other.items&(IT_ARMOR1|IT_ARMOR2|IT_ARMOR3);
  585.     other.armortype=0;
  586. };
  587.  
  588. void() rinit_poseidon =
  589. {
  590.     other.had_tbolt = (other.items&IT_LIGHTNING);
  591.     other.items=other.items|IT_LIGHTNING;
  592.     other.ammo_cells = 0;    
  593.     other.trident_time = 0;
  594. };
  595.  
  596. void() rinit_alibaba =
  597. {
  598.     local entity oself;
  599.     other.touch = alibaba_touch;
  600.     other.bulb = spawn();
  601.     oself = self;
  602.     self = other.bulb;
  603.     self.movetype = MOVETYPE_NONE;
  604.     self.solid = SOLID_NOT;
  605.     setmodel(self, string_null);
  606.     setsize(self, '0 0 0', '0 0 0');
  607.     self.effects = EF_DIMLIGHT;
  608.     self.owner = other;
  609.     self = oself;
  610. };
  611.  
  612. // SUCK: Set the model, movetype, size, think function, and touch function.
  613. // Assumes the rune is self.
  614. void() InitRune =
  615. {
  616.     local float runenum;
  617.  
  618.     runenum=self.rune_num;    
  619.     self.flags = FL_ITEM;
  620.     self.solid = SOLID_TRIGGER;
  621.     self.movetype = MOVETYPE_TOSS;
  622.     self.classname = "rune";
  623.     self.rune_init=SUB_Null;
  624.  
  625.     if (runenum == ITEM_RUNE_RESIST)
  626.     {
  627.         setmodel (self, "progs/end1.mdl");
  628.         self.rune_msg="┼ß≥⌠Φ ═ßτΘπ!\n\n╥σ≤Θ≤⌠ßεπσ";
  629.         self.rune_init_time= -1;
  630.     }
  631.     else if (runenum == ITEM_RUNE_DBLDMG)
  632.     {
  633.         setmodel (self, "progs/end2.mdl");
  634.         self.rune_msg="┬∞ßπδ ═ßτΘπ!\n\n╙⌠≥σετ⌠Φ";
  635.         self.rune_init_time= -1;
  636.     }
  637.     else if (runenum == ITEM_RUNE_HASTE)
  638.     {
  639.         setmodel (self, "progs/end3.mdl");
  640.         self.rune_msg="╚σ∞∞ ═ßτΘπ!\n\n╚ß≤⌠σ";
  641.         self.rune_init_time= -1;
  642.     }
  643.     else if (runenum == ITEM_RUNE_REGEN)
  644.     {
  645.         setmodel (self, "progs/end4.mdl");
  646.         self.rune_msg="┼∞Σσ≥ ═ßτΘπ!\n\n╥στσεσ≥ß⌠Θ∩ε";
  647.         self.rune_init_time=0;
  648.     }
  649.     else if (runenum == ITEM_RUNE_CASTLE)
  650.     {
  651.         if (teamplay&TEAM_CUSTOM_RUNES)
  652.             setmodel (self, "progs/castle.mdl");
  653.         else
  654.             setmodel (self, "progs/b_g_key.mdl");
  655.         self.rune_msg="The Castle Rune!\nYour guarding powers have increased.\n";
  656.         self.rune_init_time=-1;
  657.     }
  658.     else if (runenum == ITEM_RUNE_SIEGE)
  659.     {
  660.         if (teamplay&TEAM_CUSTOM_RUNES)
  661.             setmodel (self, "progs/siege.mdl");
  662.         else
  663.             setmodel (self, "progs/b_s_key.mdl");
  664.         self.rune_msg="The Siege Rune!\nYour offensive powers have increased.\n";
  665.         self.rune_init_time=-1;
  666.     }
  667.     else if (runenum == ITEM_RUNE_PRIEST)
  668.     {
  669.         if (teamplay&TEAM_CUSTOM_RUNES)
  670.             setmodel (self, "progs/priest.mdl");
  671.         else
  672.             setmodel (self, "progs/m_s_key.mdl");
  673.         self.rune_msg="Priest Rune!\n";
  674.         self.rune_init_time=0;
  675.     }
  676.     if (runenum == ITEM_RUNE_ARTHUR)
  677.     {
  678.         if (teamplay&TEAM_CUSTOM_RUNES)
  679.             setmodel(self, "progs/kingart.mdl");
  680.         else
  681.             setmodel (self, "progs/end1.mdl");
  682.         self.rune_msg="Rune of King Arthur!\n";
  683.         self.rune_init_time=0;
  684.     }
  685.     else if (runenum == ITEM_RUNE_WEREWOLF)
  686.     {
  687.         self.skin = 5;
  688.         setmodel (self, "progs/end3.mdl");
  689.         self.rune_msg="Werewolf Rune!\n";
  690.         self.rune_init=rinit_werewolf;
  691.         self.rune_init_time=5;
  692.     }
  693.     else if (runenum == ITEM_RUNE_WITCH)
  694.     {
  695.         if (teamplay&TEAM_CUSTOM_RUNES)
  696.             setmodel(self, "progs/witch.mdl");
  697.         else
  698.             setmodel (self, "progs/end4.mdl");
  699.         self.rune_msg="Witch Rune!\n";
  700.         self.rune_init_time=-1;
  701.     }
  702.     else if (runenum == ITEM_RUNE_VAMPIRE)
  703.     {
  704.         if (teamplay&TEAM_CUSTOM_RUNES)
  705.             setmodel (self, "progs/vamp.mdl");
  706.         else
  707.             setmodel (self, "progs/m_g_key.mdl");
  708.         self.rune_msg="You are stricken by the vampire bite!\n";
  709.         self.rune_init_time=1;
  710.         self.rune_init=rinit_vampire;
  711.     }
  712.     else if (runenum == ITEM_RUNE_VIKING)
  713.     {
  714.         if (teamplay&TEAM_CUSTOM_RUNES)
  715.             setmodel (self, "progs/viking.mdl");
  716.         else
  717.             setmodel (self, "progs/b_g_key.mdl");
  718.         self.rune_msg="The Viking Rune!\n";
  719.         self.rune_init_time=0;
  720.     }
  721.     else if (runenum == ITEM_RUNE_HERMES)
  722.     {
  723.         self.skin = 3;
  724.         setmodel (self, "progs/end1.mdl");
  725.         self.rune_msg="Rune of Hermes!\n";
  726.         self.rune_init_time=-1;
  727.         self.rune_init=rinit_hermes;
  728.     }
  729.     else if (runenum == ITEM_RUNE_VULCAN)
  730.     {
  731.         self.skin = 3;    
  732.         setmodel (self, "progs/end2.mdl");
  733.         self.rune_msg="Rune of Vulcan!\n\nSelect a weapon you do not have\nto forge it.\n";
  734.         self.rune_init_time=-1;
  735.     }
  736.     else if (runenum == ITEM_RUNE_MARS)
  737.     {
  738.         self.skin = 3;
  739.         setmodel (self, "progs/end3.mdl");
  740.         self.rune_msg="Rune of Mars!\n\nYou are powerful, but easy to damage.\n";
  741.         self.rune_init_time=-1;
  742.     }
  743.     else if (runenum == ITEM_RUNE_POSEIDON)
  744.     {
  745.         if (teamplay&TEAM_CUSTOM_RUNES)
  746.             setmodel (self, "progs/poseidon.mdl");
  747.         else
  748.             setmodel (self, "progs/m_s_key.mdl");
  749.         self.rune_msg="Rune of Poseidon!\n";
  750.         self.rune_init_time=0.5;
  751.         self.rune_init=rinit_poseidon;
  752.     }
  753.     else if (runenum == ITEM_RUNE_SHYLOCK)
  754.     {
  755.         setmodel (self, "progs/w_s_key.mdl");
  756.         self.rune_msg="Rune of Shylock!\n";
  757.         self.rune_init_time=-1;
  758.     }
  759.     else if (runenum == ITEM_RUNE_THOR)
  760.     {
  761.         if (teamplay&TEAM_CUSTOM_RUNES)
  762.             setmodel (self, "progs/thor.mdl");
  763.         else
  764.             setmodel (self, "progs/w_g_key.mdl");
  765.         self.rune_msg="Rune of Thor!\n";
  766.         self.rune_init=rinit_thor;
  767.         self.rune_init_time=-1;
  768.     }
  769.     else if (runenum == ITEM_RUNE_LOKI)
  770.     {
  771.         self.skin = 4;
  772.         setmodel (self, "progs/end4.mdl");
  773.         self.rune_msg="Rune of Loki!\n";
  774.         self.rune_init_time=-1;
  775.         self.rune_init=rinit_loki;
  776.     }
  777.     else if (runenum == ITEM_RUNE_BALDER)
  778.     {
  779.         self.skin = 4;
  780.         setmodel (self, "progs/end2.mdl");
  781.         self.rune_msg="Rune of Balder!\n";
  782.         self.rune_init_time= -1;
  783.     }
  784.     else if (runenum == ITEM_RUNE_YTR)
  785.     {
  786.         self.skin = 4;
  787.         setmodel(self, "progs/end3.mdl");
  788.         self.rune_msg = "Rune of Ytr!\n";
  789.         self.rune_init_time = -1;
  790.     }
  791.     else if (runenum == ITEM_RUNE_NINJA)
  792.     {
  793.         self.skin = 2;
  794.         setmodel (self, "progs/end1.mdl");
  795.         self.rune_msg="Ninja Rune!\n";
  796.         self.rune_init_time=-1;
  797.     }
  798.     else if (runenum == ITEM_RUNE_SAMURAI)
  799.     {
  800.         self.skin = 2;
  801.         setmodel (self, "progs/end2.mdl");
  802.         self.rune_msg="Samurai Rune!\n";
  803.         self.rune_init=rinit_samauri;
  804.         self.rune_init_time= 0;
  805.     }
  806.     else if (runenum == ITEM_RUNE_MONK)
  807.     {
  808.         self.skin = 2;
  809.         setmodel(self, "progs/end3.mdl");
  810.         self.rune_msg ="Zen Monk Rune!\n\nThe rock is unmoved by the storm.\n";
  811.         self.rune_init_time = -1;
  812.     }
  813.     else if (runenum == ITEM_RUNE_SHOGUN)
  814.     {
  815.         self.skin = 2;
  816.         setmodel(self, "progs/end4.mdl");
  817.         self.rune_msg = "Shogun Rune!\n";
  818.         self.rune_init_time = 0;
  819.     }
  820.     else if (runenum == ITEM_RUNE_WENDIGO)
  821.     {
  822.         setmodel (self, "progs/m_s_key.mdl");
  823.         self.rune_msg="Rune of Wendigo!\n";
  824.         self.rune_init_time=0;
  825.     }
  826.     else if (runenum == ITEM_RUNE_WOLVERINE)
  827.     {
  828.         setmodel (self, "progs/end4.mdl");
  829.         self.rune_msg="Rune of Wolverine!\n";
  830.         self.rune_init_time=0;
  831.     }
  832.     else if (runenum == ITEM_RUNE_GOLOM)
  833.     {
  834.         setmodel (self, "progs/end4.mdl");
  835.         self.rune_msg="Rune of Golom!\n";
  836.         self.rune_init_time=0;
  837.     }
  838.     else if (runenum == ITEM_RUNE_SARGON)
  839.     {
  840.         setmodel (self, "progs/end4.mdl");
  841.         self.rune_msg="Rune of Sargon!\n";
  842.         self.rune_init_time=-1;
  843.     }
  844.     else if (runenum == ITEM_RUNE_IFRITE)
  845.     {
  846.         self.skin = 3;
  847.         setmodel (self, "progs/w_s_key.mdl");
  848.         self.rune_msg="Ifrite Rune!\n";
  849.         self.rune_init_time=-1;
  850.     }
  851.     else if (runenum == ITEM_RUNE_KIZI)
  852.     {
  853.         setmodel (self, "progs/end3.mdl");
  854.         self.rune_msg="Rune of Kizi!\n";
  855.         self.rune_init_time=-1;
  856.  
  857.     }
  858.     else if (runenum == ITEM_RUNE_ALIBABA)
  859.     {
  860.         setmodel(self, "progs/w_g_key.mdl");
  861.         self.rune_msg="Rune of Ali Baba!\n";
  862.         self.rune_init_time = -1;
  863.         self.rune_init = rinit_alibaba;
  864.     }
  865.     else if (runenum == ITEM_RUNE_WIND)
  866.     {
  867.         setmodel(self, "progs/end1.mdl");
  868.         self.rune_msg = "Rune of Wind Arrows!\n";
  869.         self.rune_init_time = -1;
  870.     }
  871.     else if (runenum == ITEM_RUNE_SANDSTORM)
  872.     {
  873.         setmodel(self, "progs/w_g_key.mdl");
  874.         self.rune_msg = "SandStorm Rune\n";
  875.         self.rune_init_time = 0;
  876.     }
  877.     else if (runenum == ITEM_RUNE_ANKH)
  878.     {
  879.         self.skin = 3;
  880.         setmodel(self, "progs/end1.mdl");
  881.         self.rune_msg = "Ankh Rune!\n";
  882.         self.rune_init_time = 1;
  883.     }
  884.     else
  885.     {
  886.         remove(self);
  887.         return;
  888.     }
  889.  
  890.     setsize (self, '-16 -16 0', '16 16 56');
  891.     self.touch = RuneTouch;
  892.         self.nextthink = time + 120;
  893.         self.think = RuneRespawn;
  894. };
  895.  
  896. // SUCK: Tell the player which rune they have just picked up.
  897. // Assumes the player is 'other'.  This function also sets up
  898. // any player values that need to be initialized on rune pickup.
  899. void() RuneGrab =
  900. {
  901.     // Rune announcements go to the center of the screen
  902.     other.msg_center=1;
  903.  
  904.     // Tell them what rune they've just gotten
  905.     clientmsg(other, self.rune_msg);
  906.  
  907.     // Set the next rune execution time.  -1 means never execute.
  908.     if (self.rune_init_time == -1)
  909.         other.rune_time = -1;
  910.     else
  911.         other.rune_time=time + self.rune_init_time;
  912.  
  913.     // Do any initialization that might be necessary
  914.     if (self.rune_init != SUB_Null)
  915.         self.rune_init();
  916. };
  917.  
  918. // SUCK: Print a description of whatever rune the player is holding.
  919. // Assumes the player is self.
  920. void() SetRuneInfoMsg =
  921. {
  922.     if (self.rune_num == 0)
  923.         clientmsg(self,
  924. "You do not have a rune.\n");
  925.     else if (self.rune_num == ITEM_RUNE_RESIST)
  926.         clientmsg(self,
  927. "Rune of Earth Magic\nOriginal Rune Set\n\nThis rune makes you take half damage.\n");
  928.     else if (self.rune_num == ITEM_RUNE_DBLDMG)
  929.         clientmsg(self,
  930. "Rune of Black Magic\nOriginal Rune Set\n\nThis rune makes you do double damage.\n");
  931.     else if (self.rune_num == ITEM_RUNE_HASTE)
  932.         clientmsg(self,
  933. "Rune of Hell Magic\nOriginal Rune Set\n\nThis rune allows you to fire at double\nspeed.\n");
  934.     else if (self.rune_num == ITEM_RUNE_REGEN)
  935.         clientmsg(self,
  936. "Rune of Elder Magic\nOriginal Rune Set\n\nThis rune regenerates your health and\narmor.\n");
  937.  
  938.     else if (self.rune_num == ITEM_RUNE_PRIEST)
  939.         clientmsg(self, "Priest Rune\nMedieval Rune Set\n\nWith the priest rune, your health slowly\nregenerates.  Additionally, your\nprojectiles are accompanied\nby bubbles of holy water that heal your\nteammates\nand hurt your enemies.\nTo\naccess a flask of pure holy water\nselect the shotgun twice.\nFinally, you do tremendous damage to the vampire.\n");
  940.     else if (self.rune_num == ITEM_RUNE_CASTLE)
  941.         clientmsg(self, "Castle Rune\nMedieval Rune Set\n\nYour shots do double damage and you take\nhalf damage in the vicinity of your flag.\n");
  942.     else if (self.rune_num == ITEM_RUNE_SIEGE)
  943.         clientmsg(self, "Siege Rune\nMedieval Rune Set\n\nYour shots do double damage and you take\nhalf damage in the vicinity of the enemy\nflag\nor while you carry the enemy flag.\n");
  944.     else if (self.rune_num == ITEM_RUNE_ARTHUR)
  945.         clientmsg(self, "King Arthur\nMedieval Rune Set\n\nYour health and ammo slowly regenerate,\nyou\ntake half damage from enemy fire,\nand the health and ammo of nearby\nteammates also regenerate.\n");
  946.     else if (self.rune_num == ITEM_RUNE_VAMPIRE)
  947.         clientmsg(self, "Vampire Rune\nDark Ages Rune Set\n\nYour health slowly drains away, but you\ngain one third of the damage you do to\nothers.  Additionally, you have slightly\nincreased strength and resistance.\nYour axe does tremendous damage.\n");
  948.     else if (self.rune_num == ITEM_RUNE_WEREWOLF)
  949.         clientmsg(self, "Werewolf Rune\nDark Ages Rune Set\n\nYou do damage to enemies simply by\ntouching them.  You can jump very far\nand high, and you always\nhave 100 yellow armor.\n");
  950.     else if (self.rune_num == ITEM_RUNE_WITCH)
  951.         clientmsg(self, "Witch Rune\nDark Ages Rune Set\n\nWhenever you damage someone\nthere is a chance that you will curse\nhim, making him jump and fire\nuncontrollably.\n");
  952.     else if (self.rune_num == ITEM_RUNE_VIKING)
  953.         clientmsg(self, "Viking Rune\n\nDark Ages Rune Set\n\nYou do tremendous damage to the priest,\nand can pick up objects just by being\nnear them.\n\nYou cannot pick up a weapon\nmore than once.\n");
  954.     else if (self.rune_num == ITEM_RUNE_KIZI)
  955.         clientmsg(self, "Kizi Rune\nArabian Set\n\nSwing the axe to teleport to your base.\nThe lower your health, the more damage\nyou do.\n");
  956.     else if (self.rune_num == ITEM_RUNE_IFRITE)
  957.         clientmsg(self, "Ifrite Rune\nArabian Set\n\nThe Ifrite were the fire spirits of\nArabian lore, so your shots are trailed\nby fire and you regenerate in lava.\nPlus, you have a larger blast radius and\nare immune to your own splash damage.\n");
  958.     else if (self.rune_num == ITEM_RUNE_THOR)
  959.         clientmsg(self, "Rune of Thor\nNorse Set\n\nYour thunderbolt will never run out of\nammo.  You can also boil the\nwater with\nyour lightning.\n");
  960.     else if (self.rune_num == ITEM_RUNE_YTR)
  961.         clientmsg(self, "Rune of Ytr\nNorse Set\n\nYou have tremendous speed and agility,\nfor you ride atop an eight-legged horse.\nThe trick is to learn to control it.\n\nAdditionally, you decrease the strength\nof nearby enemies.\n");
  962.     else if (self.rune_num == ITEM_RUNE_NINJA)
  963.         clientmsg(self, "Ninja Rune\nJapanese Set\n\nFire your shotgun to teleport.  You move\nand fire silently.  When you die, you\nleave no corpse or ammo.\n");
  964.     else if (self.rune_num == ITEM_RUNE_SAMURAI)
  965.         clientmsg(self, "Samurai Rune\nJapanese Set\n\n2x damage with axe and\nnailguns.  1/4x damage with shotguns and\nrockets.\nRed armor regens to 200 every 25 seconds.\nAxe has 10x the reach normal.\n");
  966.     else if (self.rune_num == ITEM_RUNE_MONK)
  967.         clientmsg(self, "Zen Monk Rune\nJapansese Set\n\nIf you do not fire nor move, you will\ntake no damage from weapons.  You take\nno splash damage.\n\nYou cannot pick up a weapon\nmore than once.\n");
  968.     else if (self.rune_num == ITEM_RUNE_SHOGUN)
  969.         clientmsg(self, "Shogun Rune\nJapanese Set\n\nSelect axe and swing: teleport to\nenemy's base.  Armor takes 1/2 damage.\n");
  970.     else if (self.rune_num == ITEM_RUNE_BALDER)
  971.         clientmsg(self, "Rune of Balder\nNorse Set\n\nYou slow down your enemy's\nrate of fire by shooting them.\n");
  972.     else if (self.rune_num == ITEM_RUNE_LOKI)
  973.         clientmsg(self, "Rune of Loki\nNorse Set\n\nWhen you are stationary, you are invisible.  See the\nweb page for more details.\nhttp://linux.mit.edu/quake\n");
  974.     else if (self.rune_num == ITEM_RUNE_ALIBABA)
  975.         clientmsg(self, "Rune of AliBaba\nArabian Set\n\nWhen you touch an opponent you remove\nalmost all their ammo and get some of it.\nYou sometimes teleport to safety\nwhen in lava.\n");
  976.     else if (self.rune_num == ITEM_RUNE_WENDIGO)
  977.         clientmsg(self, "Rune of Wendigo\nMisc. Set\n\nYour health slowly decreases.  When you\nshoot someone, their velocity and\ndirection lock for a short period of\ntime.\n");
  978.     else if (self.rune_num == ITEM_RUNE_GOLOM)
  979.         clientmsg(self, "Rune of Golom\nMisc. Set\n\nYou take one quarter damage but cannot\nuse explosive weapons or\nthe whoremaker.\n");
  980.     else if (self.rune_num == ITEM_RUNE_SARGON)
  981.         clientmsg(self, "Rune of Sargon\nMisc. Set\n\nYou pick up twice the ammo and health\nthat you normally would.  You do double\ndamage to the flagcarrier, and to Golom\n");
  982.     else if (self.rune_num == ITEM_RUNE_SANDSTORM)
  983.         clientmsg(self, "Sandstorm Rune\nArabian Set\n\nRandom damage and decreased visibility\nto nearby opponents.\n");
  984.     else if (self.rune_num == ITEM_RUNE_WIND)
  985.         clientmsg(self, "Rune of Wind Arrows\nMisc. Set\n\nYour projectiles travel at twice\nthe normal speed.\n");
  986.     else if (self.rune_num == ITEM_RUNE_MARS)
  987.         clientmsg(self, "Rune of Mars\nHellenic Set\n\nYou are powerful, but\neasy to damage.\n");
  988.     else if (self.rune_num == ITEM_RUNE_POSEIDON)
  989.         clientmsg(self, "Rune of Poseidon\nHellenic Set\n\nYour thunderbolt is now a powerful trident,\nif you allow it to charge up to 100 cells.\nPlus, you cause earthquakes,\nshaking nearby enemies.\n\nYou also regenerate in water.\n");
  990.     else if (self.rune_num == ITEM_RUNE_HERMES)
  991.         clientmsg(self, "Rune of Hermes\nHellenic Set\n\nYou can fly.\n");
  992.     else if (self.rune_num == ITEM_RUNE_VULCAN)
  993.          clientmsg(self, "Rune of Vulcan\nHellenic Set\n\nYou can forge weapons and ammo\nby selecting the number of corresponding weapon.\nYou also take one half damage to your\nhealth, but move a bit slower.\n");
  994.     else
  995.         clientmsg(self, "Sorry, no rune description for\nyour rune yet.\n");
  996. };
  997.  
  998. void(entity e) RegenerateAmmo =
  999. {
  1000.     if ((e.ammo_shells>0) && (e.ammo_shells<91))
  1001.         e.ammo_shells=e.ammo_shells+10;
  1002.     if ((e.ammo_nails > 0) && (e.ammo_nails<191))
  1003.         e.ammo_nails=e.ammo_nails+10;
  1004.     if ((e.ammo_rockets>0) && (e.ammo_rockets<100) && (e.regen_rocket==1))
  1005.         e.ammo_rockets=e.ammo_rockets+1;
  1006.     if (e.regen_rocket == 0)
  1007.         e.regen_rocket = 1;
  1008.     else
  1009.         e.regen_rocket = 0;
  1010.     if (e.weapon == IT_SHOTGUN)
  1011.         e.currentammo=e.ammo_shells;
  1012.     if ((e.weapon == IT_NAILGUN) || (e.weapon == IT_SUPER_NAILGUN))
  1013.         e.currentammo=e.ammo_nails;
  1014.     if ((e.weapon == IT_ROCKET_LAUNCHER) ||
  1015.         (e.weapon == IT_GRENADE_LAUNCHER))
  1016.         e.currentammo = e.ammo_rockets;
  1017.     if (e.weapon == IT_LIGHTNING)
  1018.         e.currentammo = e.ammo_cells;
  1019.     if ((e.ammo_cells>0) && (e.ammo_cells<96))
  1020.         e.ammo_cells=e.ammo_cells+4;
  1021.     if (e.ammo_shells > 100)
  1022.         e.ammo_shells = 100;
  1023.     if (e.ammo_nails > 200)
  1024.         e.ammo_nails = 200;
  1025.     if (e.ammo_rockets > 100)
  1026.         e.ammo_rockets = 100;               
  1027.     if (e.ammo_cells > 100)
  1028.         e.ammo_cells = 100;         
  1029. };
  1030.